package cn.maihe.elg.operation.service.order;

import cn.maihe.elg.operation.centers.epoint.config.EpointCenterInfosConfig;
import cn.maihe.elg.operation.centers.fuzhou.auth.utils.FZApiCommonUtil;
import cn.maihe.elg.operation.centers.fuzhou.dto.FZBaseRespDTO;
import cn.maihe.elg.operation.centers.fuzhou.dto.handler.FZCompanyInfoDTO;
import cn.maihe.elg.operation.centers.fuzhou.dto.handler.FZRevokeApplyReqDTO;
import cn.maihe.elg.operation.centers.guogu.enums.FileTypeNameEnum;
import cn.maihe.elg.operation.centers.hymake.dto.handler.FilePushReqDTO;
import cn.maihe.elg.operation.centers.hymake.dto.handler.HyMakeCorrectApplyReqDTO;
import cn.maihe.elg.operation.centers.supports.CenterInterfaceService;
import cn.maihe.elg.operation.centers.supports.CenterInterfaceServiceFactory;
import cn.maihe.elg.operation.centers.supports.model.bo.GuaranteeRevokeResultBo;
import cn.maihe.elg.operation.common.Constants;
import cn.maihe.elg.operation.config.ImageUploadConfig;
import cn.maihe.elg.operation.config.ZtAccountInfo;
import cn.maihe.elg.operation.exception.ErrorCode;
import cn.maihe.elg.operation.exception.SystemRuntimeException;
import cn.maihe.elg.operation.model.GuoGuClientInfo;
import cn.maihe.elg.operation.model.bo.AcceptOrderBO;
import cn.maihe.elg.operation.model.dto.InnerBaseResp;
import cn.maihe.elg.operation.model.enums.AcceptOrderStatus;
import cn.maihe.elg.operation.model.enums.ApplyOrderStatus;
import cn.maihe.elg.operation.model.enums.AttachmentFileType;
import cn.maihe.elg.operation.model.enums.BidCustomerStatus;
import cn.maihe.elg.operation.model.enums.BidderLevel;
import cn.maihe.elg.operation.model.enums.BooleanEnum;
import cn.maihe.elg.operation.model.enums.CenterNoEnum;
import cn.maihe.elg.operation.model.enums.ClaimsStatus;
import cn.maihe.elg.operation.model.enums.CustomerAttachmentTypeEnum;
import cn.maihe.elg.operation.model.enums.GuaranteeStatus;
import cn.maihe.elg.operation.model.enums.GuaranteeTemplateType;
import cn.maihe.elg.operation.model.enums.InvoiceFlagEnum;
import cn.maihe.elg.operation.model.enums.InvoiceStatusEnum;
import cn.maihe.elg.operation.model.enums.NoticeTypeEnum;
import cn.maihe.elg.operation.model.enums.OrderWarnFlag;
import cn.maihe.elg.operation.model.enums.ProjectWarnFlag;
import cn.maihe.elg.operation.model.enums.RefundOrderStatus;
import cn.maihe.elg.operation.model.enums.RevokeFlagEnum;
import cn.maihe.elg.operation.model.vo.order.AcceptOrderDetailVO;
import cn.maihe.elg.operation.model.vo.order.AcceptOrderPayOperateVO;
import cn.maihe.elg.operation.model.vo.order.AcceptOrderSpdBankNoticeVO;
import cn.maihe.elg.operation.model.vo.order.AcceptOrderStatusAuditVO;
import cn.maihe.elg.operation.model.vo.order.ListAcceptOrderVO;
import cn.maihe.elg.operation.model.vo.order.OrderStatusSumVO;
import cn.maihe.elg.operation.model.vo.order.OrderTemplateIdReqVO;
import cn.maihe.elg.operation.model.vo.order.OrderTemplateIdRespVO;
import cn.maihe.elg.operation.repository.entity.AcceptOrderInfoDO;
import cn.maihe.elg.operation.repository.entity.AcceptOrderInfoDOCondition;
import cn.maihe.elg.operation.repository.entity.AcceptOrderInfoVo;
import cn.maihe.elg.operation.repository.entity.ApplyOrderInfoDO;
import cn.maihe.elg.operation.repository.entity.BidCustomerDO;
import cn.maihe.elg.operation.repository.entity.CustomerAttachmentDO;
import cn.maihe.elg.operation.repository.entity.GuaranteeAttachmentInfoDO;
import cn.maihe.elg.operation.repository.entity.GuaranteeDO;
import cn.maihe.elg.operation.repository.entity.GuaranteeInstitutionDO;
import cn.maihe.elg.operation.repository.entity.GuaranteeProgressInfoDO;
import cn.maihe.elg.operation.repository.entity.InvoiceInfoDO;
import cn.maihe.elg.operation.repository.entity.ProjectInfoDO;
import cn.maihe.elg.operation.repository.entity.RefundOrderInfoDO;
import cn.maihe.elg.operation.repository.entity.RevokeApplayOrderInfoDO;
import cn.maihe.elg.operation.repository.entity.RevokeOrderAttachmentDO;
import cn.maihe.elg.operation.repository.entity.RevokeOrderInfo;
import cn.maihe.elg.operation.repository.entity.SpdBankNotice;
import cn.maihe.elg.operation.repository.entity.SpdBankNoticeCondition;
import cn.maihe.elg.operation.repository.mapper.AcceptOrderInfoMapper;
import cn.maihe.elg.operation.service.BaseDaoService;
import cn.maihe.elg.operation.service.business.BidCustomerService;
import cn.maihe.elg.operation.service.business.CustomerAttachmentService;
import cn.maihe.elg.operation.service.business.CustomerBlacklistService;
import cn.maihe.elg.operation.service.business.ExchangeCenterService;
import cn.maihe.elg.operation.service.business.InstitutionService;
import cn.maihe.elg.operation.service.business.ProjectInfoService;
import cn.maihe.elg.operation.service.guarantee.GuaranteeService;
import cn.maihe.elg.operation.service.invoice.InvoiceInfoService;
import cn.maihe.elg.operation.service.system.UserService;
import cn.maihe.elg.operation.supports.electronicseal.anne.AnneSignService;
import cn.maihe.elg.operation.supports.invoice.nuonuo.InvoiceDownLoadHelper;
import cn.maihe.elg.operation.supports.invoice.nuonuo.InvoiceHelper;
import cn.maihe.elg.operation.supports.sms.AliyunSmsService;
import cn.maihe.elg.operation.supports.system.ElgResourceService;
import cn.maihe.elg.operation.utils.CreateGuaranteeUtil;
import cn.maihe.elg.operation.utils.DateUtil;
import cn.maihe.elg.operation.utils.ElgLogger;
import cn.maihe.elg.operation.utils.GuoGuClientInfoUtil;
import cn.maihe.elg.operation.utils.IdGenerate;
import cn.maihe.elg.operation.utils.StringUtil;
import cn.maihe.elg.operation.utils.UserContextUtil;
import cn.maihe.elg.operation.utils.ValidateUtil;
import cn.maihe.framework.starter.base.sql.PageBo;
import cn.maihe.framework.starter.mybatis.dao.MybatisDaoImpl;
import cn.maihe.framework.starter.mybatis.mapper.PlusEntityWrapper;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.validation.constraints.NotBlank;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.time.Instant;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * @Description 订单信息服务
 * @Author WJH
 * @Date 2021/03/25
 */
@Service
@Slf4j
public class AcceptOrderInfoService extends BaseDaoService<AcceptOrderInfoDO> {

    @Resource
    private UserService userService;
    @Resource
    private ProjectInfoService projectInfoService;
    @Resource
    private BidCustomerService bidCustomerService;
    @Resource
    private CustomerBlacklistService customerBlacklistService;
    @Resource
    private GuaranteeAttachmentInfoService guaranteeAttachmentInfoService;
    @Resource
    private GuaranteeProgressInfoService guaranteeProgressInfoService;
    @Resource
    private ApplyOrderInfoService applyOrderInfoService;
    @Resource
    private AliyunSmsService aliyunSmsService;
    @Resource
    private ElgResourceService elgResourceService;
    @Resource
    private AnneSignService anneSignService;
    @Resource
    private InstitutionService institutionService;
    @Resource
    private InvoiceHelper invoiceHelper;
    @Resource
    private InvoiceDownLoadHelper invoiceDownLoadHelper;
    @Resource
    private InvoiceInfoService invoiceInfoService;
    @Resource
    private GuaranteeService guaranteeService;
    @Resource
    private RevokeOrderInfoService revokeOrderInfoService;
    @Resource
    private ExchangeCenterService exchangeCenterService;
    @Resource
    private NoticeRetryInfoService noticeRetryInfoService;
    @Resource
    private CustomerAttachmentService customerAttachmentService;
    @Resource
    private ZtAccountInfo ztAccountInfo;
    @Resource
    private SpdBankNoticeService spdBankNoticeService;
    @Resource
    private RefundOrderInfoService refundOrderInfoService;
    @Resource
    private ImageUploadConfig imageUploadConfig;
    @Resource
    private EpointCenterInfosConfig epointCenterInfosConfig;

    @Value("${cn.maihe.elg.auto-guarantee-status:6}")
    private Integer [] autoGuaranteeStatus;

    public OrderStatusSumVO orderTotal() {
        Map<String, Object> paramsMap = toMapAndAddParams(new HashMap());
        return this.selectOneBySql("orderTotal", paramsMap);
    }

    public PageBo<AcceptOrderDetailVO> selectPageBySql(int pageNo, int pageSize, ListAcceptOrderVO vo) {
        Map<String, Object> paramsMap = toMapAndAddParams(vo);
        //出函时间
        if (vo.getGuaranteeTimeRange() != null && vo.getGuaranteeTimeRange().length == 2) {
            String[] rangeAy = vo.getGuaranteeTimeRange();
            if (StringUtils.isNoneBlank(rangeAy[0], rangeAy[1])) {
                paramsMap.put("startGuaranteeTime", DateUtil.parseDate(rangeAy[0] + " 00:00:00", "yyyy-MM-dd HH:mm:ss"));
                paramsMap.put("endGuaranteeTime", DateUtil.parseDate(rangeAy[1] + " 23:59:59", "yyyy-MM-dd HH:mm:ss"));
            }
        }
        //订单时间
        if (vo.getGmtCreateRange() != null && vo.getGmtCreateRange().length == 2) {
            String[] rangeAy = vo.getGmtCreateRange();
            if (StringUtils.isNoneBlank(rangeAy[0], rangeAy[1])) {
                paramsMap.put("startGmtCreate", DateUtil.parseDate(rangeAy[0] + " 00:00:00", "yyyy-MM-dd HH:mm:ss"));
                paramsMap.put("endGmtCreate", DateUtil.parseDate(rangeAy[1] + " 23:59:59", "yyyy-MM-dd HH:mm:ss"));
            }
        }  //投标截止日期
        if (vo.getBidIndateRange() != null && vo.getBidIndateRange().length == 2) {
            String[] rangeAy = vo.getBidIndateRange();
            if (StringUtils.isNoneBlank(rangeAy[0], rangeAy[1])) {
                paramsMap.put("startBidIndate", DateUtil.parseDate(rangeAy[0] + " 00:00:00", "yyyy-MM-dd HH:mm:ss"));
                paramsMap.put("endBidIndate", DateUtil.parseDate(rangeAy[1] + " 23:59:59", "yyyy-MM-dd HH:mm:ss"));
            }
        }
        //退保时间
        if (vo.getRevokeTimeRange() != null && vo.getRevokeTimeRange().length == 2) {
            String[] rangeAy = vo.getRevokeTimeRange();
            if (StringUtils.isNoneBlank(rangeAy[0], rangeAy[1])) {
                paramsMap.put("startRevokeTime", DateUtil.parseDate(rangeAy[0] + " 00:00:00", "yyyy-MM-dd HH:mm:ss"));
                paramsMap.put("endRevokeTime", DateUtil.parseDate(rangeAy[1] + " 23:59:59", "yyyy-MM-dd HH:mm:ss"));
            }
        }

        if(StringUtils.isNotBlank(vo.getRegionId())){
            if(CreateGuaranteeUtil.isSuiXingByRegionId(vo.getRegionId(),"2")){
                String[] regionIds = vo.getRegionId().split("_");
                if(regionIds.length==2){
                    paramsMap.put("regionId",regionIds[0]);
                    paramsMap.put("secondCategoryCode",regionIds[1]);
                }
            }
        }

        PageBo<AcceptOrderDetailVO> pageBo = this.selectPageBySql("selectAcceptOrderList", "selectAcceptOrderCount", paramsMap, pageNo, pageSize);
        if (!CollectionUtils.isEmpty(pageBo.getList())) {
            pageBo.getList().forEach(o -> {
                GuoGuClientInfo guoGuClientInfo = GuoGuClientInfoUtil.getClientInfoByClientId(o.getClientId());
                if(Objects.nonNull(guoGuClientInfo)){
                    if(CreateGuaranteeUtil.isSuiXingByRegionId(guoGuClientInfo.getRegionId(),"1")){
                        if("03".equals(o.getSecondCategoryCode())){
                            o.setRegionName(guoGuClientInfo.getRegionName()+"-水利平台");
                        }else {
                            o.setRegionName(guoGuClientInfo.getRegionName()+"-限额平台");
                        }
                    }else {
                        o.setRegionName(guoGuClientInfo.getRegionName());
                    }
                }
            });
        }
        if (vo.getIsDownload() == null || !vo.getIsDownload()) {
            if (!CollectionUtils.isEmpty(pageBo.getList())) {
                pageBo.getList().forEach(o -> {
                    this.fillAcceptOrderDetailVO(o);
                });
            }
        }
        return pageBo;
    }

    public List<AcceptOrderInfoDO> selectOrderByInvoice(AcceptOrderInfoVo vo) {
        return this.selectList(AcceptOrderInfoDOCondition.builder().andInvoiceIdEq(vo.getInvoiceId()).build());
    }


    @Transactional(rollbackFor = Exception.class)
    public AcceptOrderBO saveAcceptOrderBO(AcceptOrderBO bo) {
        ValidateUtil.validate(bo);

        //若投标或者投标项目已存在，则更新
        ProjectWarnFlag projectWarnFlag = this.enableAcceptByInstitution(bo);
        bo.getProjectInfo().setWarnFlag(projectWarnFlag.getFlag());
        bo.getProjectInfo().setRemark(projectWarnFlag.getDesc());
        //保存&更新投标项目
        ProjectInfoDO curProjectInfo = projectInfoService.saveOrUpdateProjectInfo(bo.getProjectInfo());
        bo.setProjectInfo(curProjectInfo);

        //保存&更新投标客户
        BidCustomerDO curBidCustomer = bidCustomerService.saveOrUpdateBidCustomer(bo.getBidCustomer());
        bo.setBidCustomer(curBidCustomer);

        //保存或更新投标客户登录账号：登录账号：社会信用代码 密码默认123456
        bo.getUserDO().setOrgId(curBidCustomer.getId());
        userService.saveOrUpdateBidUser(bo.getUserDO());


        //保存受理订单
        AcceptOrderInfoDO curAcceptOrder = bo.getAcceptOrderInfo();
        curAcceptOrder.setProjectId(curProjectInfo.getId());
        curAcceptOrder.setBidCustomerId(curBidCustomer.getId());

        OrderWarnFlag orderWarnFlag = this.isBlacklistCustomer(bo);
        curAcceptOrder.setWarnFlag(orderWarnFlag.getFlag());
        curAcceptOrder.setWarnContent(orderWarnFlag.getDesc());

        InvoiceInfoDO invoiceInfoDO = bo.getInvoiceInfoDO();
        if (invoiceInfoDO != null && !invoiceInfoDO.getInvoiceLine().isEmpty()) {
            invoiceInfoService.saveOrUpdate(invoiceInfoDO, curAcceptOrder);
            curAcceptOrder.setInvoiceId(invoiceInfoDO.getId());
        }

        this.saveOrUpdateAcceptOrderInfo(curAcceptOrder);
        bo.setAcceptOrderInfo(curAcceptOrder);

        log.info("curAcceptOrder.getCenterId():{}",curAcceptOrder.getCenterId());
        CenterNoEnum centerNoEnum = exchangeCenterService.getCenterNoEnumById(curAcceptOrder.getCenterId());
        if (CreateGuaranteeUtil.isGuoGu(centerNoEnum) || CreateGuaranteeUtil.isEPointNingDe(centerNoEnum)) {
            if (AcceptOrderStatus.WAIT_PAY.getStatus() == curAcceptOrder.getStatus()) {
                List<FilePushReqDTO.FileInfo> fileInfos = bo.getFileInfos();
                if (!CollectionUtils.isEmpty(fileInfos)) {
                    fileInfos.stream().forEach(fzFileInfo -> {
                        try {
                            this.downloadFile(curAcceptOrder, fzFileInfo);
                        } catch (Exception e) {
                            log.error("下载保存推送材料失败：{}", e.getMessage(), e);
                            throw new RuntimeException("下载保存推送材料失败：" + e.getMessage(), e);
                        }
                    });
                }
                if (CreateGuaranteeUtil.isAuditPassForCustomerInfo(centerNoEnum, curAcceptOrder.getClientId())) {
                    // 投标客户审核通过，更新投标客户信息，添加用户权限
                    BidCustomerDO getBidCustomer = bo.getBidCustomer();
                    if (BidCustomerStatus.NORMAL.getStatus() != getBidCustomer.getStatus()) {
                        bidCustomerService.customerSuccess(getBidCustomer);
                    }
                }
            }
        }

        return bo;
    }

    private void downloadFile(AcceptOrderInfoDO acceptOrderInfo, FilePushReqDTO.FileInfo fileInfo) throws Exception {
        String fileTypeName = fileInfo.getFileTypeName();
        AttachmentFileType attachmentFileType = FileTypeNameEnum.toGuaranteeAttachmentFileType(fileTypeName);
        CustomerAttachmentTypeEnum customerAttachmentTypeEnum = FileTypeNameEnum.toCustomerAttachmentFileType(fileTypeName);
        if (attachmentFileType != null) {
            this.saveOrUpdateGuaranteeAttachInfo(attachmentFileType, acceptOrderInfo, fileInfo);
        } else if (customerAttachmentTypeEnum != null) {
            this.saveOrUpdateCustomerAttachInfo(customerAttachmentTypeEnum, acceptOrderInfo, fileInfo);
        }

    }

    private void saveOrUpdateGuaranteeAttachInfo(AttachmentFileType attachmentFileType, AcceptOrderInfoDO acceptOrderInfo, FilePushReqDTO.FileInfo fileInfo) throws Exception {
        String fileUrl = fileInfo.getUrl();
        String md5Value = fileInfo.getMd5Value();
        String acceptOrderNo = acceptOrderInfo.getAcceptOrderNo();
        GuaranteeAttachmentInfoDO guaranteeAttachmentInfo = guaranteeAttachmentInfoService.getTypeAttachmentByAcceptOrderNo(acceptOrderNo, attachmentFileType);
        if (guaranteeAttachmentInfo != null) {
            md5Value = guaranteeAttachmentInfo.getFileMd5();
        }
        if (guaranteeAttachmentInfo == null) {
            Path tmpPath = elgResourceService.downloadByURL(fileUrl);
            String relativePath = elgResourceService.transferAndSaveFile(tmpPath, "ofd", acceptOrderNo, fileInfo.getFileTypeName());
            md5Value = elgResourceService.getFileMD5AsHex(elgResourceService.getAbsolutePath(relativePath));
            Files.deleteIfExists(tmpPath);

            guaranteeAttachmentInfo = new GuaranteeAttachmentInfoDO();
            guaranteeAttachmentInfo.setId(IdGenerate.getId());
            guaranteeAttachmentInfo.setCenterId(acceptOrderInfo.getCenterId());
            guaranteeAttachmentInfo.setOrgId(acceptOrderInfo.getOrgId());
            guaranteeAttachmentInfo.setAcceptOrderNo(acceptOrderInfo.getAcceptOrderNo());
            guaranteeAttachmentInfo.setType(attachmentFileType.getType());
            guaranteeAttachmentInfo.setFileName(fileInfo.getFileTypeName());
            guaranteeAttachmentInfo.setFileType(fileInfo.getFileType());
            guaranteeAttachmentInfo.setFileMd5(md5Value);
            guaranteeAttachmentInfo.setFilePath(relativePath);
            guaranteeAttachmentInfo.setRemark("新增" + attachmentFileType.getDesc());
            guaranteeAttachmentInfo.setFileUrl(fileInfo.getUrl());
            guaranteeAttachmentInfo.setFileId(fileInfo.getFileId());

            guaranteeAttachmentInfoService.insert(guaranteeAttachmentInfo);
        } else if (md5Value == null || !md5Value.equalsIgnoreCase(guaranteeAttachmentInfo.getFileMd5())) {
            Path tmpPath = elgResourceService.downloadByURL(fileUrl);
            String relativePath = elgResourceService.transferAndSaveFile(tmpPath, "ofd", acceptOrderNo, fileInfo.getFileTypeName());
            md5Value = elgResourceService.getFileMD5AsHex(elgResourceService.getAbsolutePath(relativePath));
            Files.deleteIfExists(tmpPath);

            guaranteeAttachmentInfo.setCenterId(acceptOrderInfo.getCenterId());
            guaranteeAttachmentInfo.setOrgId(acceptOrderInfo.getOrgId());
            guaranteeAttachmentInfo.setAcceptOrderNo(acceptOrderInfo.getAcceptOrderNo());
            guaranteeAttachmentInfo.setType(attachmentFileType.getType());
            guaranteeAttachmentInfo.setFileName(fileInfo.getFileTypeName());
            guaranteeAttachmentInfo.setFileType(fileInfo.getFileType());
            guaranteeAttachmentInfo.setFileMd5(md5Value);
            guaranteeAttachmentInfo.setFilePath(relativePath);
            guaranteeAttachmentInfo.setRemark("更新" + attachmentFileType.getDesc());
            guaranteeAttachmentInfo.setFileUrl(fileInfo.getUrl());
            guaranteeAttachmentInfo.setFileId(fileInfo.getFileId());

            guaranteeAttachmentInfoService.updateById(guaranteeAttachmentInfo);
        }

    }

    private void saveOrUpdateCustomerAttachInfo(CustomerAttachmentTypeEnum customerAttachmentType, AcceptOrderInfoDO acceptOrderInfo, FilePushReqDTO.FileInfo fileInfo) throws Exception {
        String fileUrl = fileInfo.getUrl();
        String md5Value = fileInfo.getMd5Value();
        Long bidCustomerId = acceptOrderInfo.getBidCustomerId();
        CustomerAttachmentDO customerAttachment = customerAttachmentService.getCustomerAttachment(bidCustomerId, customerAttachmentType);
        if (customerAttachment != null) {
            md5Value = customerAttachment.getFileMd5();
        }
        if (customerAttachment == null) {
            Path tmpPath = elgResourceService.downloadByURL(fileUrl);
//            String relativePath = elgResourceService.transferAndSaveFile(tmpPath, "ofd", bidCustomerId.toString(), fileInfo.getFileTypeName());
            String relativePath = UUID.randomUUID().toString() + "." + elgResourceService.getFileType(tmpPath);
            md5Value = elgResourceService.getFileMD5AsHex(tmpPath);
            Path registerDir = Paths.get(imageUploadConfig.getPath(), Constants.REGIST_IMAGE_PATH);
            if (Files.notExists(registerDir)) {
                Files.createDirectories(registerDir);
            }
            Path registerImg = registerDir.resolve(relativePath);
            Files.copy(tmpPath, registerImg, StandardCopyOption.REPLACE_EXISTING);

            Files.deleteIfExists(tmpPath);

            customerAttachment = new CustomerAttachmentDO();
            customerAttachment.setId(IdGenerate.getId());
            customerAttachment.setBidderId(bidCustomerId);
            customerAttachment.setAttachType(customerAttachmentType.getType());
            customerAttachment.setAttachPath(relativePath);
            customerAttachment.setAttachFileName(relativePath);
            customerAttachment.setFileMd5(md5Value);
            customerAttachment.setFileUrl(fileUrl);

            customerAttachmentService.insert(customerAttachment);
        } else if (md5Value == null || !md5Value.equalsIgnoreCase(customerAttachment.getFileMd5())) {
            Path tmpPath = elgResourceService.downloadByURL(fileUrl);
//            String relativePath = elgResourceService.transferAndSaveFile(tmpPath, "ofd", bidCustomerId.toString(), fileInfo.getFileTypeName());
            String relativePath = UUID.randomUUID().toString() + "." + elgResourceService.getFileType(tmpPath);
            md5Value = elgResourceService.getFileMD5AsHex(tmpPath);
            Path registerDir = Paths.get(imageUploadConfig.getPath(), Constants.REGIST_IMAGE_PATH);
            if (Files.notExists(registerDir)) {
                Files.createDirectories(registerDir);
            }
            Path registerImg = registerDir.resolve(relativePath);
            Files.copy(tmpPath, registerImg, StandardCopyOption.REPLACE_EXISTING);

            Files.deleteIfExists(tmpPath);


            customerAttachment.setBidderId(bidCustomerId);
            customerAttachment.setAttachType(customerAttachmentType.getType());
            customerAttachment.setAttachPath(relativePath);
            customerAttachment.setAttachFileName(relativePath);
            customerAttachment.setFileMd5(md5Value);
            customerAttachment.setFileUrl(fileUrl);

            customerAttachmentService.updateById(customerAttachment);
        }

    }

    /**
     * 交易中心订单号查询
     */
    public AcceptOrderDetailVO getAcceptOrderDetailById(Long id) {
        Assert.notNull(id, () -> "Id不能为空");
        Map<String, Object> params = Maps.newHashMap();
        params.put("id", id);
        AcceptOrderDetailVO acceptOrderDetailVO = this.selectOneBySql("getAcceptOrderDetailById", params);
        SpdBankNotice spdBankNotice = spdBankNoticeService.selectOne(SpdBankNoticeCondition.builder().andAcceptOrderNoEq(acceptOrderDetailVO.getAcceptOrderNo()).build());
        if (spdBankNotice != null) {
            acceptOrderDetailVO.setBankSerialNo(String.format("%s%s%s%s", spdBankNotice.getCoreSerNo(), "（附言：", spdBankNotice.getAttach(), "）"));
        }
        acceptOrderDetailVO = this.fillAcceptOrderDetailVO(acceptOrderDetailVO);

        return acceptOrderDetailVO;
    }

    public AcceptOrderDetailVO fillAcceptOrderDetailVO(AcceptOrderDetailVO acceptOrderDetailVO) {
        List<GuaranteeAttachmentInfoDO> aList = guaranteeAttachmentInfoService.getAllAttachmentByAcceptOrderNo(acceptOrderDetailVO.getAcceptOrderNo());
        if (!CollectionUtils.isEmpty(aList)) {
            aList.forEach(l -> {
                if (AttachmentFileType.TYPE_0.getType() == l.getType()) {
                    acceptOrderDetailVO.setAllOFDFile(l);
                } else if (AttachmentFileType.TYPE_1.getType() == l.getType()) {
                    acceptOrderDetailVO.setOrigApplyFile(l);
                } else if (AttachmentFileType.TYPE_2.getType() == l.getType()) {
                    acceptOrderDetailVO.setOrgQualificationFile(l);
                } else if (AttachmentFileType.TYPE_3.getType() == l.getType()) {
                    acceptOrderDetailVO.setOrgBusinessLicFile(l);
                } else if (AttachmentFileType.TYPE_4.getType() == l.getType()) {
                    acceptOrderDetailVO.setOpenAccountFile(l);
                } else if (AttachmentFileType.TYPE_5.getType() == l.getType()) {
                    acceptOrderDetailVO.setPayProveFile(l);
                } else if (AttachmentFileType.TYPE_6.getType() == l.getType()) {
                    acceptOrderDetailVO.setReceiveProveFile(l);
                } else if (AttachmentFileType.TYPE_7.getType() == l.getType()) {
                    acceptOrderDetailVO.setGuaranteeFile(l);
                } else if (AttachmentFileType.TYPE_8.getType() == l.getType()) {
                    acceptOrderDetailVO.setInvoiceFile(l);
                } else if (AttachmentFileType.TYPE_9.getType() == l.getType()) {
                    acceptOrderDetailVO.setOtherFile(l);
                } else if (AttachmentFileType.TYPE_11.getType() == l.getType()) {
                    acceptOrderDetailVO.setProtocolFile(l);
                } else if (AttachmentFileType.TYPE_12.getType() == l.getType()) {
                    acceptOrderDetailVO.setProtocolUnSignedFile(l);
                } else if (AttachmentFileType.TYPE_14.getType() == l.getType()) {
                    acceptOrderDetailVO.setGuaranteeXmlFile(l);
                } else if (AttachmentFileType.TYPE_16.getType() == l.getType()) {
                    acceptOrderDetailVO.setInvoiceReversalFile(l);
                }

            });
        }
        return acceptOrderDetailVO;
    }

    /**
     * 交易中心订单号查询
     */
    public AcceptOrderInfoDO getByCenterOrderId(Long centerId, Long orgId, String centerOrderId) {
        Assert.notNull(centerId, () -> "centerId不能为空");
        Assert.notNull(orgId, () -> "orgId不能为空");
        Assert.hasText(centerOrderId, () -> "centerOrderId不能为空");
        return this.selectOne(AcceptOrderInfoDOCondition.builder().andCenterIdEq(centerId).andOrgIdEq(orgId).andCenterOrderIdEq(centerOrderId).build());
    }

    public boolean existsCenterOrderId(Long centerId, String centerOrderId) {
        Assert.notNull(centerId, () -> "centerId不能为空");
        Assert.hasText(centerOrderId, () -> "centerOrderId不能为空");
        return this.exists(AcceptOrderInfoDOCondition.builder().andCenterIdEq(centerId).andCenterOrderIdEq(centerOrderId).build());
    }

    /**
     * 平台内部唯一受理订单号查询
     */
    public AcceptOrderInfoDO getByAcceptOrderNo(String acceptOrderNo) {
        Assert.hasText(acceptOrderNo, () -> "acceptOrderNo不能为空");
        return this.selectOne(AcceptOrderInfoDOCondition.builder().andAcceptOrderNoEq(acceptOrderNo).build());
    }

    /**
     * 保存&更新 受理订单信息
     */
    public AcceptOrderInfoDO saveOrUpdateAcceptOrderInfo(AcceptOrderInfoDO cur) {
        AcceptOrderInfoDO dbDO = this.getByAcceptOrderNo(cur.getAcceptOrderNo());
        if (dbDO != null) {
            cur.setId(dbDO.getId());
            cur.setGmtModified(Date.from(Instant.now()));
            this.updateById(cur);
        } else {
            cur.setGuaranteeCount(this.selectList(AcceptOrderInfoDOCondition.builder()
                    .andBidCustomerIdEq(cur.getBidCustomerId())
                    .andProjectIdEq(cur.getProjectId())
                    .andStatusEq(AcceptOrderStatus.HAS_OUT_GUARANTEE.getStatus()).build()).size());
            cur.setId(cur.getId() != null ? cur.getId() : IdGenerate.getId());
            cur.setGmtCreate(Date.from(Instant.now()));
            cur.setGmtModified(cur.getGmtCreate());
            this.insert(cur);
        }
        return cur;
    }

    public Integer updateByAcceptOrderNo(AcceptOrderInfoDO updateDO, String acceptOrderNo) {
        AcceptOrderInfoDOCondition condition = AcceptOrderInfoDOCondition.builder().andAcceptOrderNoEq(acceptOrderNo);
        return this.update(updateDO, condition.build());
    }


    /**
     * 是否黑名单列表或者客户信息被标记黑名单
     */
    private OrderWarnFlag isBlacklistCustomer(AcceptOrderBO bo) {
        String customerCreditCode = bo.getBidCustomer().getBidderCreditCode();
        //是否为黑名单中投标客户
        boolean exists = customerBlacklistService.existsCreditCode(customerCreditCode, bo.getCenterId(), bo.getOrgId(), null);
        if (exists) {
            return OrderWarnFlag.CUSTOMER_BLACKLIST;
        }

        //投标客户是否被标记黑名单
        BidCustomerDO dbCustomerDo = bidCustomerService.getByCreditCode(customerCreditCode, bo.getCenterId(), bo.getOrgId(), null);
        if (dbCustomerDo != null && dbCustomerDo.getBlacklistFlag() != null && dbCustomerDo.getBlacklistFlag().intValue() == BooleanEnum.TRUE.getIndex()) {
            return OrderWarnFlag.CUSTOMER_BLACKLIST;
        }
        return OrderWarnFlag.NORMAL;
    }

    /**
     * 该订单能否由该出函机构承接
     * 1. 该订单的担保类型 不在该指定 出函机构的业务范围 ，则返回 false
     * 2. 出函机构设置指定该订单项目都不受理，则返回 false
     * 其他都返回true
     */
    private ProjectWarnFlag enableAcceptByInstitution(AcceptOrderBO bo) {
        //项目预警标识：预警标识0正常 1出函机构无法受理该项目 FIXME | TODO 暂无法识别出函机构能够承接该项目
        //1. 该订单的担保类型 不在该指定 出函机构的业务范围 ，则返回 false TODO 暂无法识别出函机构能够承接该项目

        return ProjectWarnFlag.NORMAL;
    }

    /**
     * 待初审 审核操作
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean auditWaitFirstTrail(AcceptOrderStatusAuditVO vo) {
        AcceptOrderInfoDO curDO = this.selectById(vo.getId());
        if (curDO.getStatus() != null && curDO.getStatus().intValue() == vo.getStatus() && AcceptOrderStatus.WAIT_FIRST_TRAIL.getStatus() == vo.getStatus()) {

            AcceptOrderInfoDO updateDO = AcceptOrderInfoDO.builder().id(curDO.getId()).remark(vo.getAuditRemark())
                    .gmtModified(Date.from(Instant.now())).build();
            //审核通过 进入 尽调状态
            if (vo.getAuditStatus().intValue() == 1) {
                updateDO.setStatus(AcceptOrderStatus.WAIT_TUNE_UP.getStatus());
            }

            GuaranteeProgressInfoDO progressInfoDO = GuaranteeProgressInfoDO.builder().status(vo.getStatus())
                    .id(IdGenerate.getId()).acceptOrderNo(curDO.getAcceptOrderNo()).centerOrderId(curDO.getCenterOrderId())
                    .orderType(AcceptOrderStatus.orderType).title("初审")
                    .auditStatus(vo.getAuditStatus()).auditRemark(vo.getAuditRemark())
                    .operateUserName(UserContextUtil.getCurUserName() != null ? UserContextUtil.getCurUserName() : "system").build();

            this.updateById(updateDO);
            guaranteeProgressInfoService.saveGuaranteeProgressInfo(progressInfoDO);
            return true;
        } else {
            throw new SystemRuntimeException(ErrorCode.INVALID, "status", String.valueOf(vo.getStatus()));
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public boolean auditGuaranteeTemplateId(AcceptOrderStatusAuditVO vo) {
        AcceptOrderInfoDO curDO = this.selectById(vo.getId());
        if (curDO.getStatus() != null && curDO.getStatus().intValue() == vo.getStatus() && AcceptOrderStatus.WAIT_SUBMIT_FIRST_TRAIL.getStatus() == vo.getStatus()) {

            AcceptOrderInfoDO updateDO = AcceptOrderInfoDO.builder().id(curDO.getId()).remark(vo.getAuditRemark())
                    .gmtModified(Date.from(Instant.now())).build();
            //审核通过 进入 待支付确认
            if (vo.getAuditStatus().intValue() == 1) {
                updateDO.setStatus(AcceptOrderStatus.WAIT_PAY_CONFIRM.getStatus());
            } else { //不通过则返回待签署
                updateDO.setStatus(AcceptOrderStatus.WAIT_FIRST_TRAIL.getStatus());
            }
            this.updateById(updateDO);
            return true;
        } else {
            throw new SystemRuntimeException(ErrorCode.INVALID, "status", String.valueOf(vo.getStatus()));
        }
    }


    @Transactional(rollbackFor = Exception.class)
    public Boolean auditWaitTuneUp(AcceptOrderStatusAuditVO vo) {
        AcceptOrderInfoDO curDO = this.selectById(vo.getId());
        if (curDO.getStatus() != null && curDO.getStatus().intValue() == vo.getStatus() && AcceptOrderStatus.WAIT_TUNE_UP.getStatus() == vo.getStatus()) {

            AcceptOrderInfoDO updateDO = AcceptOrderInfoDO.builder().id(curDO.getId()).remark(vo.getAuditRemark())
                    .gmtModified(Date.from(Instant.now())).build();
            //审核通过 进入 待报价
            if (vo.getAuditStatus().intValue() == 1) {
                updateDO.setStatus(AcceptOrderStatus.WAIT_OFFER.getStatus());
            }

            GuaranteeProgressInfoDO progressInfoDO = GuaranteeProgressInfoDO.builder().status(vo.getStatus())
                    .id(IdGenerate.getId()).acceptOrderNo(curDO.getAcceptOrderNo()).centerOrderId(curDO.getCenterOrderId())
                    .orderType(AcceptOrderStatus.orderType).title("尽调")
                    .auditStatus(vo.getAuditStatus()).auditRemark(vo.getAuditRemark())
                    .operateUserName(UserContextUtil.getCurUserName() != null ? UserContextUtil.getCurUserName() : "system").build();

            this.updateById(updateDO);
            guaranteeProgressInfoService.saveGuaranteeProgressInfo(progressInfoDO);
            return true;
        } else {
            throw new SystemRuntimeException(ErrorCode.INVALID, "status", String.valueOf(vo.getStatus()));
        }
    }

    /**
     * 报价操作
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean auditWaitOffer(AcceptOrderStatusAuditVO vo) {
        AcceptOrderInfoDO curDO = this.selectById(vo.getId());
        if (curDO.getStatus() != null && curDO.getStatus().intValue() == vo.getStatus() && AcceptOrderStatus.WAIT_OFFER.getStatus() == vo.getStatus()) {

            AcceptOrderInfoDO updateDO = AcceptOrderInfoDO.builder().id(curDO.getId()).remark(vo.getAuditRemark())
                    .gmtModified(Date.from(Instant.now())).build();
            //审核通过 进入 待支付同时关联保函模板
            Assert.notNull(vo.getGuaranteeFee(), "保费报价不能为空");

            updateDO.setGuaranteeFee(vo.getGuaranteeFee());
            updateDO.setStatus(AcceptOrderStatus.WAIT_PAY.getStatus());
            updateDO.setTemplateId(vo.getGuaranteeTemplateId());

            GuaranteeProgressInfoDO progressInfoDO = GuaranteeProgressInfoDO.builder().status(vo.getStatus())
                    .id(IdGenerate.getId()).acceptOrderNo(curDO.getAcceptOrderNo()).centerOrderId(curDO.getCenterOrderId())
                    .orderType(AcceptOrderStatus.orderType).title("报价")
                    .auditStatus(1).offerAmt(vo.getGuaranteeFee()).auditRemark(vo.getAuditRemark())
                    .operateUserName(UserContextUtil.getCurUserName() != null ? UserContextUtil.getCurUserName() : "system").build();

            this.updateById(updateDO);
            guaranteeProgressInfoService.saveGuaranteeProgressInfo(progressInfoDO);

            //发送待支付短信通知
            BidCustomerDO bidCustomerDO = bidCustomerService.selectById(curDO.getBidCustomerId());
            String targetMobile = bidCustomerDO.getBidderContactTel();
            String guaranteeFee = new BigDecimal(updateDO.getGuaranteeFee()).multiply(BigDecimal.valueOf(100L)).setScale(2, RoundingMode.HALF_UP).toString();
            aliyunSmsService.sendWaitPaySms(targetMobile, curDO.getSectionName(), guaranteeFee);

            return true;
        } else {
            throw new SystemRuntimeException(ErrorCode.INVALID, "status", String.valueOf(vo.getStatus()));
        }
    }

    /**
     * 待支付确认审核:选择支付流水 支付确认审核通过则直接 签署生成 担保保函书
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean manualAuditWaitPayConfirm(AcceptOrderStatusAuditVO vo, String acceptOrderNo) {
        // 校验 申请书 & 反担保承诺书 签章文件是否存在
        guaranteeAttachmentInfoService.getGuaAttPath(acceptOrderNo, AttachmentFileType.TYPE_11);

        String coreSerNo = vo.getCoreSerNo();
        Assert.hasText(coreSerNo, () -> "核心交易流水号不能为空");
        SpdBankNotice dbSpdBankNotice = spdBankNoticeService.selectOne(SpdBankNoticeCondition.builder().andCoreSerNoEq(coreSerNo).build());
        if (dbSpdBankNotice == null) {
            throw new SystemRuntimeException(ErrorCode.NOTEXISTS, "核心交易流水号[" + coreSerNo + "]对应的支付流水不存在");
        }
        vo.setPayTime(DateUtil.formatDateStr(dbSpdBankNotice.getTransDate(), DateUtil.FORMAT_TRADEDATE, DateUtil.FORMAT_DATE));
        //待支付-[手动选择支付流水状态变更]-待支付确认--审核操作
        boolean waitPayConfirmResult = auditWaitPayConfirm(vo);
        ElgLogger.info(log, l -> l.info("coreSerNo={} <= 手动审核操作完成，审核状态：{}，审核执行结果：{}", coreSerNo, vo.getAuditStatus().intValue(), waitPayConfirmResult));

        if (waitPayConfirmResult && vo.getAuditStatus().intValue() == 1) {
            //审核通过则更新支付流水信息
            dbSpdBankNotice.setAcceptOrderNo(acceptOrderNo);
            Integer updateRow = spdBankNoticeService.updateById(dbSpdBankNotice);
            if (updateRow != 1) {
                ElgLogger.error(log, l -> l.error("coreSerNo={} <= 更新入金通知异常，受影响行数{}", coreSerNo, updateRow));
                throw new SystemRuntimeException(ErrorCode.ERROR, "核心交易流水号[" + coreSerNo + "]更新支付流水失败");
            }
        }
        return true;
    }

    /**
     * 待支付确认审核:支付确认审核通过则直接 签署生成 担保保函书
     */
    @Transactional(rollbackFor = Exception.class)
    public void autoAuditWaitPayConfirm(SpdBankNotice spdBankNotice) {
        //是否存在入金通知的 母账户账号=担保公司收款账户 来账账号=投标人基本账号 交易金额=保费金额以及附言中包含标编号
        String coreSerNo = spdBankNotice.getCoreSerNo();
        String parentAcctNo = spdBankNotice.getParentAcctNo();
        String subAccount = spdBankNotice.getSubAccount();
        String acctNo = spdBankNotice.getAcctNo();
        String transAmt = spdBankNotice.getTransAmt();
        String attach = spdBankNotice.getAttach();
        Assert.hasText(coreSerNo, () -> "核心交易流水号不能为空");
        Assert.hasText(parentAcctNo, () -> "母账户账户不能为空");
        Assert.hasText(acctNo, () -> "来账账号不能为空");
        Assert.hasText(transAmt, () -> "交易金额不能为空");
        Assert.hasText(attach, () -> "附言不能为空");

        String ztAccNo = ztAccountInfo.getAccNo();
        if (!ztAccNo.equals(parentAcctNo)) {
            ElgLogger.warn(log, l -> l.warn("核心交易流水号:{} << 母账户账号[{}]不是系统配置的担保公司收款账号，暂不处理。{}", coreSerNo, parentAcctNo, JSON.toJSONString(spdBankNotice)));
            return;
        }

        //选择待支付状态且投标人基本户账号和保费金额一致的受理订单号
        Map<String, Object> params = new HashMap<>();
        params.put("payerAcctNo", acctNo);
        params.put("guaranteeFee", StringUtil.yuanToFen(transAmt));
        List<AcceptOrderSpdBankNoticeVO> spdBankNoticeVoList = selectListBySql("selectByPayerAccNoAndGuaranteeFee", params);
        if (!CollectionUtils.isEmpty(spdBankNoticeVoList)) {
            AcceptOrderSpdBankNoticeVO acceptOrder = spdBankNoticeVoList.stream()
                    .filter(o -> {
                        if (
                                (
                                    (CreateGuaranteeUtil.isGuoGuNonSuiXing(o.getAcceptOrderNo(),o.getClientId())
                                        && StringUtils.contains(attach, o.getAcceptOrderNo()))
                                    || StringUtils.contains(attach, o.getProjectCode())
                                    || (CreateGuaranteeUtil.isMeiShanByAcceptOrderNo(o.getAcceptOrderNo())
                                            && StringUtils.isNotBlank(subAccount)
                                            && StringUtils.isNotBlank(subAccount.trim())
                                            && subAccount.equals(o.getSubAccount()))
                                )

                                && o.getTemplateId() != null

                                && (Arrays.asList(autoGuaranteeStatus).contains(o.getStatus())
                                || (CreateGuaranteeUtil.isGuoGuByAcceptOrderNo(o.getAcceptOrderNo())
                                && o.getStatus() == AcceptOrderStatus.WAIT_PAY.getStatus()))
                        ) {
                            return true;
                        } else {
                            ElgLogger.info(log, l -> l.error("核心交易流水号:{} << 母账户账号[{}],记账子单元编号[{}],来账账号[{}],交易金额[{}元],附言[{}] 未检测到正确的订单状态:项目[{}]受理订单号[{}]保函编号[{}]订单状态[{}]保函模板ID[{}]",
                                    coreSerNo, parentAcctNo,subAccount, acctNo, transAmt, attach, o.getProjectCode(), o.getAcceptOrderNo(), o.getGuaranteeNo(), o.getStatus(), o.getTemplateId()));
                            return false;
                        }
                    })
                    .findFirst().orElse(null);

            if (acceptOrder != null) {
                AcceptOrderStatusAuditVO auditVO = new AcceptOrderStatusAuditVO();
                auditVO.setId(acceptOrder.getId());
                auditVO.setStatus(acceptOrder.getStatus());
                auditVO.setAuditStatus(1);
                auditVO.setPayTime(DateUtil.formatDateStr(spdBankNotice.getTransDate(), DateUtil.FORMAT_TRADEDATE, DateUtil.FORMAT_DATE));
                auditVO.setTemplateId(acceptOrder.getTemplateId());
                auditVO.setAuditRemark("系统检测到转账已到账，自动审核通过(浦发入账查询)");
                ElgLogger.info(log, l -> l.info("核心交易流水号:{} << 母账户账号[{}],记账子单元编号[{}],来账账号[{}],交易金额[{}元],附言[{}] 检测识别为项目[{}]受理订单号[{}]保函编号[{}]的转账记录并做自动审核通过", coreSerNo, parentAcctNo,subAccount, acctNo, transAmt, attach,
                        acceptOrder.getProjectCode(), acceptOrder.getAcceptOrderNo(), acceptOrder.getGuaranteeNo()));

                //自动审核
                auditWaitPayConfirm(auditVO);

                //更新入金通知记录
                SpdBankNotice updateNotice = new SpdBankNotice();
                updateNotice.setId(spdBankNotice.getId());
                updateNotice.setAcceptOrderNo(acceptOrder.getAcceptOrderNo());
                spdBankNoticeService.updateById(updateNotice);
            } else {
                ElgLogger.info(log, l -> l.info("核心交易流水号:{} << 母账户账号[{}],记账子单元编号[{}],来账账号[{}],交易金额[{}元],附言[{}] 没有匹配到项目", coreSerNo, parentAcctNo,subAccount, acctNo, transAmt, attach));
            }
        } else {
            ElgLogger.info(log, l -> l.info("核心交易流水号:{} << 母账户账号[{}],记账子单元编号[{}],来账账号[{}],交易金额[{}元],附言[{}] 没有查询到项目", coreSerNo, parentAcctNo,subAccount, acctNo, transAmt, attach));
        }

    }

    /**
     * 待支付确认审核:支付确认审核通过则直接 签署生成 担保保函书
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.NESTED)
    public Boolean auditWaitPayConfirm(AcceptOrderStatusAuditVO vo) {
        AcceptOrderInfoDO curDO = this.selectById(vo.getId());

        //待支付和 待支付确认 都可以后管管理员直接确认
        if (curDO.getStatus() != null && curDO.getStatus().intValue() == vo.getStatus()
                && (AcceptOrderStatus.WAIT_PAY.getStatus() == vo.getStatus() ||
                AcceptOrderStatus.WAIT_PAY_CONFIRM.getStatus() == vo.getStatus()
        )) {
            GuaranteeProgressInfoDO progressInfoDO = GuaranteeProgressInfoDO.builder().status(vo.getStatus())
                    .id(IdGenerate.getId()).acceptOrderNo(curDO.getAcceptOrderNo()).centerOrderId(curDO.getCenterOrderId())
                    .orderType(AcceptOrderStatus.orderType).title("支付确认")
                    .auditStatus(vo.getAuditStatus()).auditRemark(vo.getAuditRemark())
                    .operateUserName(UserContextUtil.getCurUserName() != null ? UserContextUtil.getCurUserName() : "system").build();
            guaranteeProgressInfoService.saveGuaranteeProgressInfo(progressInfoDO);

            curDO.setRemark(vo.getAuditRemark());
            curDO.setGmtModified(Date.from(Instant.now()));

            CenterNoEnum centerNoEnum = exchangeCenterService.getCenterNoEnumById(curDO.getCenterId());
            //审核通过 进入 待出函
            if (vo.getAuditStatus().intValue() == 1) {
                String payTime = vo.getPayTime();
                Assert.hasText(payTime, () -> "到账时间不能为空");
                try {
                    LocalDate.parse(payTime, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                } catch (Exception e) {
                    throw new RuntimeException("到账时间格式错误");
                }

                if (CreateGuaranteeUtil.isGuoGu(centerNoEnum)) {
                    ProjectInfoDO projectInfoDO = projectInfoService.selectById(curDO.getProjectId());
                    Long guoGuTemplateId = CreateGuaranteeUtil.getGuoGuTemplateId(centerNoEnum, curDO.getClientId(), projectInfoDO.getSecondCategoryCode());
                    vo.setTemplateId(guoGuTemplateId);
                    curDO.setTemplateId(guoGuTemplateId);
                } else if (CreateGuaranteeUtil.isMeiShan(centerNoEnum)) {
                    vo.setTemplateId(GuaranteeTemplateType.meishanGuaranteeTemplate.getTemplateId());
                    curDO.setTemplateId(GuaranteeTemplateType.meishanGuaranteeTemplate.getTemplateId());
                } else {
                    curDO.setTemplateId(vo.getTemplateId());
                }
                curDO.setPayTime(payTime);
                curDO.setStatus(AcceptOrderStatus.WAIT_OUT_GUARANTEE.getStatus());
                //创建  申请订单服务
                curDO.setApplyOrderNo(IdGenerate.genApplyOrderNo());
                curDO.setInvoiceNo(vo.getInvoiceNo());
                // 发起担保保函书 签署流程

                try {
                    InvoiceInfoDO invoiceInfoDO = null;
                    if (CreateGuaranteeUtil.isIssueInvoice(centerNoEnum, curDO.getClientId())) {
                        //小于1000元开电子票，其他线下开之后后管上送发票号
                        //                    if (curDO.getGuaranteeFee() < 100000) {
                        //未开票则发起开票申请
                        if (curDO.getInvoiceFlag() == null || curDO.getInvoiceFlag() == InvoiceFlagEnum.INVOICEPRE.getValue()) {
                            invoiceInfoDO = applyOrderInfoService.invoice(curDO, false, curDO.getInvoiceLine());
                        } else {
                            //已开票或开票中
                            invoiceInfoDO = invoiceInfoService.selectById(curDO.getInvoiceId());
                        }

                        if (invoiceInfoDO == null) {
                            throw new RuntimeException("查无开票记录，请先开票申请后再试");
                        }

                        //电子发票接口开票方式，得确认开票成功后再去开函
                        if (1 == invoiceInfoDO.getInvoiceMode() && invoiceInfoDO.getStatus() != InvoiceStatusEnum.INVOICED.getValue()) {
                            invoiceInfoDO = invoiceHelper.queryInvoiceResultAndDownload(invoiceInfoDO);
                        }

                        if (StringUtils.isBlank(invoiceInfoDO.getInvoiceNo()) ||
                                invoiceInfoDO.getStatus() != InvoiceStatusEnum.INVOICED.getValue()) {
                            throw new RuntimeException("当前开票状态为[" + InvoiceStatusEnum.getLabel(invoiceInfoDO.getStatus()) + "]稍后再试");
                        }
                        curDO.setInvoiceFlag(InvoiceFlagEnum.INVOICED.getValue());
                        curDO.setInvoiceNo(invoiceInfoDO.getInvoiceNo());
                    }
                    boolean pushTF = applyOrderInfoService.pushPayResult(curDO, true);
                    curDO.setPushPayResultFlag(pushTF ? 1 : 0);
                    this.updateById(curDO);
                    if (pushTF) {
                        //同步开函
                        applyOrderInfoService.applyGuarantee(curDO, invoiceInfoDO, null, false);
                        ProjectInfoDO project = ProjectInfoDO.builder()
                                .id(curDO.getProjectId())
                                .templateId(curDO.getTemplateId())
                                .build();
                        projectInfoService.updateById(project);
                        return true;
                    } else {
                        throw new RuntimeException("支付结果推送失败");
                    }
                } catch (Exception e) {
                    log.error("开函失败：{}", e.getMessage(), e);
                    if (e instanceof SystemRuntimeException) {
                        throw (SystemRuntimeException) e;
                    } else if (e.getCause() != null && e.getCause() instanceof SystemRuntimeException) {
                        throw (SystemRuntimeException) e.getCause();
                    } else {
                        throw new RuntimeException("开函失败：" + e.getMessage());
                    }
                }

            } else {
                //审核不通过，则关闭订单，回调通知中心
                curDO.setStatus(AcceptOrderStatus.CANCEL.getStatus());
                curDO.setRemark(vo.getAuditRemark());
                curDO.setGmtModified(new Date());
                //审核不通过,通知中心支付失败
                boolean pushTF = applyOrderInfoService.pushPayResult(curDO, false);
                curDO.setPushPayResultFlag(pushTF ? 1 : 0);
                this.updateById(curDO);

                //审核不通过,通知中心
                pushGuarantee4Reject(curDO);
            }


            return true;
        } else {
            throw new SystemRuntimeException(ErrorCode.INVALID, "status", String.valueOf(vo.getStatus()));
        }
    }

    /**
     * 保函批改后待支付确认审核:支付确认审核通过则直接 签署生成 担保保函书
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.NESTED)
    public Boolean correctAuditWaitPayConfirm(AcceptOrderStatusAuditVO vo, GuaranteeDO correctGuaranteeDO) {
        AcceptOrderInfoDO curDO = this.selectById(vo.getId());

        //待支付和 待支付确认 都可以后管管理员直接确认
        if (curDO.getStatus() != null && curDO.getStatus().intValue() == vo.getStatus()
                && (AcceptOrderStatus.WAIT_PAY.getStatus() == vo.getStatus() ||
                AcceptOrderStatus.WAIT_PAY_CONFIRM.getStatus() == vo.getStatus()
        )) {
            GuaranteeProgressInfoDO progressInfoDO = GuaranteeProgressInfoDO.builder().status(vo.getStatus())
                    .id(IdGenerate.getId()).acceptOrderNo(curDO.getAcceptOrderNo()).centerOrderId(curDO.getCenterOrderId())
                    .orderType(AcceptOrderStatus.orderType).title("支付确认")
                    .auditStatus(vo.getAuditStatus()).auditRemark(vo.getAuditRemark())
                    .operateUserName(UserContextUtil.getCurUserName() != null ? UserContextUtil.getCurUserName() : "system").build();
            guaranteeProgressInfoService.saveGuaranteeProgressInfo(progressInfoDO);

            curDO.setRemark(vo.getAuditRemark());
            curDO.setGmtModified(Date.from(Instant.now()));


            //审核通过 进入 待出函
            if (vo.getAuditStatus().intValue() == 1) {
                String payTime = vo.getPayTime();
                Assert.hasText(payTime, () -> "到账时间不能为空");
                try {
                    LocalDate.parse(payTime, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                } catch (Exception e) {
                    throw new RuntimeException("到账时间格式错误");
                }
                curDO.setTemplateId(vo.getTemplateId());
                curDO.setPayTime(payTime);
                curDO.setStatus(AcceptOrderStatus.WAIT_OUT_GUARANTEE.getStatus());
                //创建  申请订单服务
                curDO.setApplyOrderNo(IdGenerate.genApplyOrderNo());
                curDO.setInvoiceNo(vo.getInvoiceNo());
                // 发起担保保函书 签署流程
                try {
                    InvoiceInfoDO invoiceInfoDO = null;
                    //小于1000元开电子票，其他线下开之后后管上送发票号
//                    if (curDO.getGuaranteeFee() < 100000) {
                    //未开票则发起开票申请
                    if (curDO.getInvoiceFlag() == null || curDO.getInvoiceFlag() == InvoiceFlagEnum.INVOICEPRE.getValue()) {
                        invoiceInfoDO = applyOrderInfoService.invoice(curDO, false, null);
                    } else {
                        //已开票或开票中
                        invoiceInfoDO = invoiceInfoService.selectById(curDO.getInvoiceId());
                    }

                    if (invoiceInfoDO == null) {
                        throw new RuntimeException("查无开票记录，请先开票申请后再试");
                    }

                    //电子发票接口开票方式，得确认开票成功后再去开函
                    if (1 == invoiceInfoDO.getInvoiceMode() && invoiceInfoDO.getStatus() != InvoiceStatusEnum.INVOICED.getValue()) {
                        invoiceInfoDO = invoiceHelper.queryInvoiceResultAndDownload(invoiceInfoDO);
                    }

                    if (StringUtils.isBlank(invoiceInfoDO.getInvoiceNo()) ||
                            invoiceInfoDO.getStatus() != InvoiceStatusEnum.INVOICED.getValue()) {
                        throw new RuntimeException("当前开票状态为[" + InvoiceStatusEnum.getLabel(invoiceInfoDO.getStatus()) + "]稍后再试");
                    }
                    curDO.setInvoiceFlag(InvoiceFlagEnum.INVOICED.getValue());
                    curDO.setInvoiceNo(invoiceInfoDO.getInvoiceNo());
                    //todo 开票完成并推送支付结果至中心成功后，进入开函中状态，并异步进行开函业务处理
                    //开函成功并推送至中心，若开函失败后管手动触发再次开函

                    boolean pushTF = applyOrderInfoService.pushPayResult(curDO, true);
                    curDO.setPushPayResultFlag(pushTF ? 1 : 0);
                    this.updateById(curDO);
                    if (pushTF) {
                        //同步开函
                        applyOrderInfoService.applyGuarantee(curDO, invoiceInfoDO, correctGuaranteeDO, false);
                        ProjectInfoDO project = ProjectInfoDO.builder()
                                .id(curDO.getProjectId())
                                .templateId(curDO.getTemplateId())
                                .build();
                        projectInfoService.updateById(project);
                        return true;
                    } else {
                        throw new RuntimeException("支付结果推送失败");
                    }
                } catch (Exception e) {
                    log.error("开函失败：{}", e.getMessage(), e);
                    if (e instanceof SystemRuntimeException) {
                        throw (SystemRuntimeException) e;
                    } else if (e.getCause() != null && e.getCause() instanceof SystemRuntimeException) {
                        throw (SystemRuntimeException) e.getCause();
                    } else {
                        throw new RuntimeException("开函失败：" + e.getMessage());
                    }
                }

            } else {
                //审核不通过，则关闭订单，回调通知中心
                curDO.setStatus(AcceptOrderStatus.CANCEL.getStatus());
                curDO.setRemark(vo.getAuditRemark());
                curDO.setGmtModified(new Date());

                //审核不通过,通知中心支付失败
                boolean pushTF = applyOrderInfoService.pushPayResult(curDO, false);
                curDO.setPushPayResultFlag(pushTF ? 1 : 0);
                this.updateById(curDO);

                //审核不通过,通知中心
                pushGuarantee4Reject(curDO);
            }


            return true;
        } else {
            throw new SystemRuntimeException(ErrorCode.INVALID, "status", String.valueOf(vo.getStatus()));
        }
    }


    @Transactional(rollbackFor = Exception.class)
    public Boolean submitSignedInfo(AcceptOrderPayOperateVO vo) {
        AcceptOrderInfoDO curDO = this.selectById(vo.getId());
        CenterNoEnum centerNoEnum = exchangeCenterService.getCenterNoEnumById(curDO.getCenterId());
        GuaranteeAttachmentInfoDO attachmentInfoDO = guaranteeAttachmentInfoService.getTypeAttachmentByAcceptOrderNo(curDO.getAcceptOrderNo(), AttachmentFileType.TYPE_11);
        if (attachmentInfoDO == null) {
            throw new SystemRuntimeException(ErrorCode.ERROR, "请先签署保函申请书");
        }

        //资质文件
        Path qualificationPath = customerAttachmentService.getBidQualificationFile(curDO.getBidCustomerId(), centerNoEnum, curDO.getClientId());
        if (qualificationPath == null || Files.notExists(qualificationPath)) {
            throw new RuntimeException("资质文件不存在");
        }
        guaranteeAttachmentInfoService.saveOrUpdateAttachmentInfo(curDO, qualificationPath, AttachmentFileType.TYPE_2, "资质证书");


        //营业执照
        Path licensePath = customerAttachmentService.getBidBusinessLicFile(curDO.getBidCustomerId(), centerNoEnum, curDO.getClientId());
        if (licensePath == null || Files.notExists(licensePath)) {
            throw new RuntimeException("营业执照不存在");
        }
        guaranteeAttachmentInfoService.saveOrUpdateAttachmentInfo(curDO, licensePath, AttachmentFileType.TYPE_3, "营业执照");


        AcceptOrderInfoDO updateAccept = AcceptOrderInfoDO.builder().id(curDO.getId())
                .status(AcceptOrderStatus.WAIT_PAY_CONFIRM.getStatus())
                .inviteCode(vo.getInviteCode())
                .gmtModified(Date.from(Instant.now())).remark("申请书已签署,请及时转账支付保费").build();
        this.updateById(updateAccept);

        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    public Boolean submitPayInfo(AcceptOrderPayOperateVO vo) {

        AcceptOrderInfoDO curDO = this.selectById(vo.getId());
        if (!"1".equals(vo.getPayStatus())) {
            throw new SystemRuntimeException(ErrorCode.ERROR, "请先确认已转账保费");
        }
        GuaranteeAttachmentInfoDO attachmentInfoDO = guaranteeAttachmentInfoService.getTypeAttachmentByAcceptOrderNo(curDO.getAcceptOrderNo(), AttachmentFileType.TYPE_11);
        if (attachmentInfoDO == null) {
            throw new SystemRuntimeException(ErrorCode.ERROR, "请签章保函担保申请书");
        }

        AcceptOrderInfoDO updateAccept = AcceptOrderInfoDO.builder().id(curDO.getId())
                .inviteCode(vo.getInviteCode())
                .gmtModified(Date.from(Instant.now())).remark("保函担保申请书已签章待审核").build();

        if (AcceptOrderStatus.WAIT_PAY.getStatus() == curDO.getStatus()) {
            updateAccept.setStatus(AcceptOrderStatus.WAIT_PAY_CONFIRM.getStatus());
        }

        this.updateById(updateAccept);
//        无需安妮认证
//        createSqContract(curDO);

        return true;
    }

    /**
     * 更新业务编码
     *
     * @param vo 更新对象
     * @return 更新结果
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean submitInviteCodeInfo(AcceptOrderPayOperateVO vo) {

        AcceptOrderInfoDO curDO = this.selectById(vo.getId());
        AcceptOrderInfoDO updateAccept = AcceptOrderInfoDO.builder().id(curDO.getId()).inviteCode(vo.getInviteCode())
                .gmtModified(Date.from(Instant.now())).build();
        this.updateById(updateAccept);
//        无需安妮认证
//        createSqContract(curDO);

        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    public void revokeOrder(AcceptOrderInfoDO orderInfoDO, RevokeApplayOrderInfoDO revokeApplayOrderInfoDO) {
        orderInfoDO.setStatus(AcceptOrderStatus.CANCEL.getStatus());
        this.updateById(orderInfoDO);
        MybatisDaoImpl.run().insert(revokeApplayOrderInfoDO);

    }

    @Transactional(rollbackFor = Exception.class)
    public Boolean cancelOrder(AcceptOrderPayOperateVO vo) {
        AcceptOrderInfoDO acceptOrderInfo = this.selectById(vo.getId());
        CenterNoEnum centerNoEnum = exchangeCenterService.getCenterNoEnumById(acceptOrderInfo.getCenterId());
        if (CreateGuaranteeUtil.isGiveupNotice(centerNoEnum)) {
            String acceptOrderNo = acceptOrderInfo.getAcceptOrderNo();
            boolean giveupNotice = false;
            try {
                CenterInterfaceService cService = CenterInterfaceServiceFactory.getByCenterNoEnum(centerNoEnum);
                InnerBaseResp innerBaseResp = cService.giveupNotice(acceptOrderNo);
                if (innerBaseResp != null && innerBaseResp.getRespCode().isSuccess()) {
                    giveupNotice = true;
                    ElgLogger.info(log, log -> log.info("受理订单号[{}] << 金融机构放弃申请成功：响应报文：{}", acceptOrderNo, JSON.toJSONString(innerBaseResp)));
                } else {
                    ElgLogger.error(log, log -> log.error("受理订单号[{}] << 金融机构放弃申请失败,响应报文：{}", acceptOrderNo, JSON.toJSONString(innerBaseResp)));
                }
            } catch (Exception e) {
                ElgLogger.error(log, log -> log.error("受理订单号[{}] << 金融机构放弃申请异常：{}", acceptOrderNo, e.getMessage(), e));
            }

            if(giveupNotice){
                AcceptOrderInfoDO updateAccept = AcceptOrderInfoDO.builder().id(vo.getId()).status(AcceptOrderStatus.CANCEL.getStatus())
                        .gmtModified(Date.from(Instant.now())).userModified(UserContextUtil.getCurUserName()).remark("订单取消").build();
                this.updateById(updateAccept);
            }
            return giveupNotice;
        } else {
            AcceptOrderInfoDO updateAccept = AcceptOrderInfoDO.builder().id(vo.getId()).status(AcceptOrderStatus.CANCEL.getStatus())
                    .gmtModified(Date.from(Instant.now())).userModified(UserContextUtil.getCurUserName()).remark("订单取消").build();
            this.updateById(updateAccept);
            this.pushGuarantee4Reject(acceptOrderInfo);
        }
        return true;
    }

    private void pushGuarantee4Reject(AcceptOrderInfoDO acceptOrderInfo) {
        GuaranteeInstitutionDO guaranteeInstitutionDO = institutionService.selectById(acceptOrderInfo.getInstitutionId());
        GuaranteeDO tmp = new GuaranteeDO();
        tmp.setCenterId(acceptOrderInfo.getCenterId());
        tmp.setOrgId(acceptOrderInfo.getOrgId());
        tmp.setGuaranteeNo(acceptOrderInfo.getGuaranteeNo());
        tmp.setCenterOrderId(acceptOrderInfo.getCenterOrderId());
        tmp.setAcceptOrderNo(acceptOrderInfo.getAcceptOrderNo());
        tmp.setGuarantorName(guaranteeInstitutionDO.getGuarantorName());
        tmp.setRate(acceptOrderInfo.getFeeRate());
        applyOrderInfoService.pushGuarantee("0", tmp, null,false);
    }

    public void updateGuaranteeCount(Long bidCustomerId, Long projectId) {
        Map params = new HashMap();
        params.put("bidCustomerId", bidCustomerId);
        params.put("projectId", projectId);
        MybatisDaoImpl.of(AcceptOrderInfoMapper.class).updateBySql("updateGuaranteeCount", params);
    }

    public AcceptOrderInfoDO getByGuaranteeNo(String guaranteeNo) {
        Assert.hasText(guaranteeNo, () -> "guaranteeNo不能为空");
        return this.selectOne(AcceptOrderInfoDOCondition.builder().andGuaranteeNoEq(guaranteeNo).build());
    }

    public AcceptOrderInfoDO getByGuaranteeNo(Long centerId, Long orgId, String guaranteeNo) {
        Assert.hasText(guaranteeNo, () -> "guaranteeNo不能为空");
        return this.selectOne(AcceptOrderInfoDOCondition.builder().andCenterIdEq(centerId).andOrgIdEq(orgId).andGuaranteeNoEq(guaranteeNo).build());
    }

//    public AcceptOrderInfoDO getBySerialNum(Long centerId, Long orgId, String serialNum) {
//        Assert.hasText(serialNum, () -> "serialNum不能为空");
//        return this.selectOne(AcceptOrderInfoDOCondition.builder().andCenterIdEq(centerId).andOrgIdEq(orgId).andserialNumEq(serialNum).build());
//    }
//
//    public AcceptOrderInfoDO getByGuaranteeNoOrSerialNum(Long centerId, Long orgId, String guaranteeNo, String serialNum) {
//        Assert.hasText(serialNum, () -> "serialNum不能为空");
//        return this.selectOne(AcceptOrderInfoDOCondition.builder().andCenterIdEq(centerId).andOrgIdEq(orgId).and().orGuaranteeNoEq(guaranteeNo).orserialNumEq(serialNum).build());
//    }

    /**
     * 退保申请审核
     *
     * @param curDO
     * @param auditStatus 1 通过 0不通过
     * @param auditRemark
     */
    public void auditRevokeOrder(AcceptOrderInfoDO curDO, Integer auditStatus, String auditRemark) {
        RevokeOrderInfo revokeOrderInfo = revokeOrderInfoService.getRevokeOrderInfo(curDO.getCenterId(), curDO.getOrgId(), curDO.getGuaranteeNo());
        Assert.notNull(revokeOrderInfo, () -> "查无此保函退保申请记录");

        AcceptOrderInfoDO updateAcceptOrder = AcceptOrderInfoDO.builder().id(curDO.getId())
                .remark(auditRemark).build();
        GuaranteeDO guaranteeDO = guaranteeService.getGuaranteeByAcceptOrderNo(curDO.getAcceptOrderNo());
        GuaranteeDO updateGuarantee = null;
        if (guaranteeDO != null && guaranteeDO.getId() != null) {
            updateGuarantee = new GuaranteeDO();
            updateGuarantee.setId(guaranteeDO.getId());
        }

        Boolean auditStatusTF = (auditStatus != null && auditStatus == 1) ? true : false;
        Date curDate = new Date();
        if (auditStatusTF) {
            updateAcceptOrder.setRevokeFlag(RevokeFlagEnum.SUCCESS.getFlag());
            updateAcceptOrder.setRevokeTime(curDate);
            updateAcceptOrder.setStatus(AcceptOrderStatus.REVOKE_SUCCESS.getStatus());
            revokeOrderInfo.setStatus(BooleanEnum.TRUE.getIndex());
            if (updateGuarantee != null) {
                updateGuarantee.setGuaranteeStatus(GuaranteeStatus.FINISH_UNPROTECT.getStatus());
                updateGuarantee.setRevokeTime(curDate);
                updateGuarantee.setRemark("退保申请审核通过:" + auditRemark);
            }
            //退保审核通过设置发票冲红标识为待冲红
            invoiceInfoService.updateInvoiceReversal(curDO.getInvoiceId());
        } else {
            updateAcceptOrder.setRevokeFlag(RevokeFlagEnum.FAILURE.getFlag());
            updateAcceptOrder.setRevokeTime(curDate);
            updateAcceptOrder.setStatus(AcceptOrderStatus.REVOKE_FAIL.getStatus());
            revokeOrderInfo.setStatus(BooleanEnum.TRUE.getIndex());
            if (updateGuarantee != null) {
                updateGuarantee.setRevokeTime(curDate);
                updateGuarantee.setRemark("退保申请审核拒绝:" + auditRemark);
            }
        }
        this.updateById(updateAcceptOrder);
        revokeOrderInfoService.updateById(revokeOrderInfo);
        if (updateGuarantee != null) {
            guaranteeService.updateById(updateGuarantee);
        }

        CenterNoEnum centerNoEnum = exchangeCenterService.getCenterNoEnumById(curDO.getCenterId());
        //退保结果通知
        GuaranteeRevokeResultBo bo = new GuaranteeRevokeResultBo();
        //原退保申请的业务流水号
        bo.setCenterOrderId(revokeOrderInfo.getRemark());
        bo.setGuaranteeNo(curDO.getGuaranteeNo());
        bo.setAuditPass(auditStatusTF);
        bo.setAuditRemark(auditRemark);
        bo.setRevokeOrderId(revokeOrderInfo.getId());
        bo.setAcceptOrderNo(curDO.getAcceptOrderNo());

        try {
            NoticeTypeEnum noticeTypeEnum = NoticeTypeEnum.revoke_apply_result;
            CenterInterfaceService cService = CenterInterfaceServiceFactory.getByCenterNoEnum(centerNoEnum);
            InnerBaseResp innerBaseResp = cService.noticeGuaranteeRevokeResult(bo);
            if (innerBaseResp != null && innerBaseResp.getRespCode().isSuccess()) {
                ElgLogger.info(log, log -> log.info("受理订单号[{}] >> 异步推送退保申请结果成功：响应报文：{}", curDO.getAcceptOrderNo(), JSON.toJSONString(innerBaseResp)));
            } else {
                ElgLogger.info(log, log -> log.info("受理订单号[{}] >> 异步推送退保申请结果失败,待下次通知：响应报文：{}", curDO.getAcceptOrderNo(), JSON.toJSONString(innerBaseResp)));
                noticeRetryInfoService.saveOrUpdateNoticeRetryInfo(noticeTypeEnum, curDO.getCenterId(), curDO.getOrgId(), curDO.getAcceptOrderNo(), bo, null, innerBaseResp);
            }
        } catch (Exception e) {
            InnerBaseResp innerBaseResp = InnerBaseResp.exception(e.getMessage());
            ElgLogger.info(log, log -> log.info("受理订单号[{}] >> 异步推送退保申请异常：{}", curDO.getAcceptOrderNo(), e.getMessage(), e));
            noticeRetryInfoService.saveOrUpdateNoticeRetryInfo(NoticeTypeEnum.revoke_apply_result, curDO.getCenterId(), curDO.getOrgId(), curDO.getAcceptOrderNo(), bo, null, innerBaseResp
            );
        }

    }

    @Transactional(rollbackFor = Exception.class)
    public Boolean revokeApply(AcceptOrderInfoDO orderInfoDO) {
        if (orderInfoDO == null) {
            throw new SystemRuntimeException(ErrorCode.ERROR, "查无此投保申请记录");
        }
        RevokeFlagEnum flagEnum = RevokeFlagEnum.resolve(orderInfoDO.getRevokeFlag());
        if (flagEnum == RevokeFlagEnum.SUCCESS || flagEnum == RevokeFlagEnum.FAILURE) {
            throw new SystemRuntimeException(ErrorCode.ERROR, "退保状态为[" + flagEnum + "]，不能再申请退保");
        }
        if (flagEnum == RevokeFlagEnum.PROCESSING) {
            throw new SystemRuntimeException(ErrorCode.ERROR, "退保审核中，请耐心等待审核结果");
        }
        if (flagEnum != RevokeFlagEnum.INIT) {
            throw new SystemRuntimeException(ErrorCode.ERROR, "退保状态不是待退保状态，不能申请退保");
        }

        if (orderInfoDO.getStatus() == AcceptOrderStatus.FINISH.getStatus()) {
            throw new SystemRuntimeException(ErrorCode.ERROR, "保函已完成，不能退保申请");
        }
        if (orderInfoDO.getStatus() == AcceptOrderStatus.CANCEL.getStatus()) {
            throw new SystemRuntimeException(ErrorCode.ERROR, "保函已取消，不能退保申请");
        }
        if (orderInfoDO.getStatus() != AcceptOrderStatus.HAS_OUT_GUARANTEE.getStatus()) {
            throw new SystemRuntimeException(ErrorCode.ERROR, "已出函状态才能发起退保，未出函前可调用放弃投保申请");
        }


        String reason = "投标企业申请退保";
        AcceptOrderInfoDO updateOrderInfo = AcceptOrderInfoDO.builder().id(orderInfoDO.getId())
                .status(AcceptOrderStatus.REVOKE_PROCESSING.getStatus()).revokeTime(new Date())
                .revokeFlag(RevokeFlagEnum.PROCESSING.getFlag()).remark(reason).build();
        this.updateById(updateOrderInfo);

        ProjectInfoDO project = projectInfoService.selectById(orderInfoDO.getProjectId());

        RevokeOrderInfo revokeOrderInfo = RevokeOrderInfo.builder()
                .id(IdGenerate.getId())
                .centerId(orderInfoDO.getCenterId())
                .orgId(orderInfoDO.getOrgId())
                //通过保函编号关联受理订单号
                .revokeNo(orderInfoDO.getGuaranteeNo())
                .note(reason)
                //备注字段存储 业务流水号
                .remark(orderInfoDO.getAcceptOrderNo())
                .projectCode(project.getProjectCode()).projectName(orderInfoDO.getProjectName())
                .sectionCode(project.getSectionCode()).sectionName(orderInfoDO.getSectionName())
                .tenderer(project.getTenderer()).status(0)
                .build();

        revokeOrderInfoService.saveRevokeOrderInfo(revokeOrderInfo);
        return true;
    }

    /**
     * 人工退保
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean manualQuitApply(String acceptOrderNo) {
        AcceptOrderInfoDO updateOrder = AcceptOrderInfoDO.builder().status(AcceptOrderStatus.CANCEL.getStatus())
                .remark("人工退保，订单取消").revokeFlag(1).build();
        this.updateByAcceptOrderNo(updateOrder, acceptOrderNo);

        ApplyOrderInfoDO updateApply = ApplyOrderInfoDO.builder().status(ApplyOrderStatus.CANCEL.getStatus())
                .remark("人工退保，订单取消").build();
        applyOrderInfoService.updateByAcceptOrderNo(updateApply, acceptOrderNo);

        GuaranteeDO updateGuarantee = GuaranteeDO.builder().guaranteeStatus(GuaranteeStatus.FINISH_UNPROTECT.getStatus())
                .remark("人工退保，保函已解保").build();
        guaranteeService.updateByAcceptOrderNo(updateGuarantee, acceptOrderNo);
        return true;
    }

    /**
     * 自动取消订单
     * 订单在支付确认状态下，但已经开标的订单，能不能设置一下过期未转账出函的，自动跳到已取消状态里去。目前都是有空了手动操作取消的
     *
     * @return
     */
    public long updateAutoCancelAcceptOrder(Long enableCenterId) {
        Map<String, Object> paramsMap = new HashMap<>();
//        paramsMap.put("enableCenterId", enableCenterId);
        return this.updateBySql("updateAutoCancelAcceptOrder", paramsMap);
    }

    /**
     * 修改未设置保费的订单，莆田中心适用
     *
     * @param bidCustomerDB
     */
    public void updateUnFeeAcceptOrderInfo(BidCustomerDO bidCustomerDB) {
        if (bidCustomerDB.getStatus() != null && BidCustomerStatus.NORMAL.getStatus() == bidCustomerDB.getStatus()) {
            BidderLevel bidderLevel = BidderLevel.resolve(bidCustomerDB.getBidderLevel());
            EpointCenterInfosConfig.LevelInfo levelInfo = null;
            EpointCenterInfosConfig.CenterInfo centerInfo = epointCenterInfosConfig.getAuthConfig(CenterNoEnum.PUTIAN).getCenterInfo();
            switch (bidderLevel) {
                case ONE: {
                    levelInfo = centerInfo.getOneLevel();
                    break;
                }
                case TWO: {
                    levelInfo = centerInfo.getTwoLevel();
                    break;
                }
                case THREE: {
                    levelInfo = centerInfo.getThreeLevel();
                    break;
                }
            }
            if (levelInfo != null) {
                String feeRate = levelInfo.getFeeRate();
                String minFeeYuan = levelInfo.getMinFeeYuan();
                List<AcceptOrderInfoDO> acceptOrderInfoDOS = this.selectNoFeeRateByBidderId(bidCustomerDB.getId());
                if (!CollectionUtils.isEmpty(acceptOrderInfoDOS)) {
                    acceptOrderInfoDOS.stream().filter(o -> o.getStatus() <= AcceptOrderStatus.WAIT_PAY_CONFIRM.getStatus())
                            .forEach(order -> {
                                ProjectInfoDO projectInfoDO = projectInfoService.selectById(order.getProjectId());
                                order.setFeeRate(feeRate);
                                order.setGuaranteeFee(this.calcGuaranteeFee(projectInfoDO.getBidBond(), feeRate, minFeeYuan));
                                this.updateById(order);
                            });
                }
            }
        }
    }

    public Long calcGuaranteeFee(Long bidBond, String feeRate, String minFeeYuan) {
        if (bidBond == null || StringUtils.isBlank(feeRate)) {
            throw new RuntimeException("保费计算异常:保证金为空或费率为空");
        }
        BigDecimal points = new BigDecimal("100");
        //0.01% 转0.0001
        BigDecimal rate = new BigDecimal(feeRate).divide(points, 6, RoundingMode.HALF_UP);

        BigDecimal guaranteeFee = new BigDecimal(bidBond).multiply(rate);
        Long guaranteeFeeFen = guaranteeFee.longValue();
        long minFeeFen = new BigDecimal(minFeeYuan).multiply(points).longValue();
        if (guaranteeFeeFen < minFeeFen) {
            guaranteeFeeFen = minFeeFen;
        }
        return guaranteeFeeFen;
    }

    public List<AcceptOrderInfoDO> selectNoFeeRateByBidderId(Long bidCustomerId) {
        AcceptOrderInfoDOCondition condition = AcceptOrderInfoDOCondition.builder().andBidCustomerIdEq(bidCustomerId)
                .andFeeRateEq("-");
        return this.selectList(condition.build());
    }

    /**
     * 自动取消订单 不区分交易中心
     * 订单在支付确认状态下，但已经开标的订单，能不能设置一下过期未转账出函的，自动跳到已取消状态里去。目前都是有空了手动操作取消的
     *
     * @return
     */
    public long updateAutoCancelAcceptOrder() {
        Map<String, Object> paramsMap = new HashMap<>();
        return this.updateBySql("updateAutoCancelAcceptOrder", paramsMap);
    }

    public OrderTemplateIdRespVO defaultTemplateId(OrderTemplateIdReqVO vo) {
        OrderTemplateIdRespVO resp = new OrderTemplateIdRespVO();
        resp.setTemplateId(projectInfoService.selectById(vo.getProjectId()).getTemplateId());
        return resp;
    }

    /**
     * 查询订单匹配的支付流水
     *
     * @param acceptOrderNo 受理订单号
     * @return List<SpdBankNotice>
     * @author Alan
     * @date 2023/12/14 16:44
     */
    public List<SpdBankNotice> selectMatchPayInfos(String acceptOrderNo) {
        AcceptOrderInfoDO acceptOrderInfoDO = getByAcceptOrderNo(acceptOrderNo);
        BidCustomerDO bidCustomerDO = bidCustomerService.selectById(acceptOrderInfoDO.getBidCustomerId());
        String payerAcctNo = bidCustomerDO.getBankCardNum().replace(" ", "");
        String payeeAcctNo = ztAccountInfo.getAccNo();

        Long guaranteeFee = acceptOrderInfoDO.getGuaranteeFee();
        List<SpdBankNotice> spdBankNoticeList = spdBankNoticeService.selectMatchPayInfos(payerAcctNo, payeeAcctNo, guaranteeFee,acceptOrderInfoDO.getSubAccount());
        return spdBankNoticeList;
    }

    /**
     * 批改保函，重新出函
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean correctGuarantee(AcceptOrderInfoDO orderInfo, GuaranteeDO guaranteeDO, HyMakeCorrectApplyReqDTO req) {
        try {
            orderInfo.setProjectName(req.getBusinessDetail());
            orderInfo.setSectionName(req.getSectionName());
            orderInfo.setStatus(AcceptOrderStatus.WAIT_PAY_CONFIRM.getStatus());
            this.updateById(orderInfo);

            ProjectInfoDO project = projectInfoService.selectById(orderInfo.getProjectId());
            project.setProjectCode(req.getInsureArea());
            project.setProjectName(req.getBusinessDetail());
            project.setSectionCode(req.getSectionCode());
            project.setSectionName(req.getSectionName());
            project.setTenderer(req.getInsuredName());
            project.setTendererCreditCode(req.getInsuredIdNo());
            projectInfoService.updateById(project);

            guaranteeDO.setServiceEndTime(DateUtils.parseDate(req.getInsurEndDate(), DateUtil.FORMAT_DATE));
            //.setServiceendtime(DateUtil.formateDate(Date.from(vo.getBidOpenTime().toInstant().plus(vo.getValidPeriod() + 28, ChronoUnit.DAYS)), "yyyy-MM-dd HH:mm:ss")); //是	保险止期
            guaranteeService.updateById(guaranteeDO);

            AcceptOrderStatusAuditVO auditVO = new AcceptOrderStatusAuditVO();
            auditVO.setId(orderInfo.getId());
            auditVO.setStatus(orderInfo.getStatus());
            auditVO.setAuditStatus(1);
            auditVO.setPayTime(orderInfo.getPayTime());
            auditVO.setTemplateId(orderInfo.getTemplateId());
            auditVO.setAuditRemark("批改接口，自动审核通过重新出函");

            //重新出函
            this.correctAuditWaitPayConfirm(auditVO, guaranteeDO);
        } catch (Exception e) {
            log.error("重新出函失败：{}", e.getMessage(), e);
            throw new SystemRuntimeException(ErrorCode.ERROR, "批改信息，重新出函失败");
        }
        return true;
    }


    /**
     * 保函作废
     */
    @Transactional(rollbackFor = Exception.class)
    public FZBaseRespDTO invalidGuarantee(String acceptInfoId, String backReasonDetail) {

        AcceptOrderInfoDO acceptOrderInfoDO = this.selectById(Long.parseLong(acceptInfoId));
        BidCustomerDO bidCustomerDO = bidCustomerService.selectById(acceptOrderInfoDO.getBidCustomerId());
//        FZRevokeApplyReqDTO req = context.getReq();

        FZRevokeApplyReqDTO req = new FZRevokeApplyReqDTO();
        req.setPolicyNo(acceptOrderInfoDO.getGuaranteeNo());

        req.setBankName(bidCustomerDO.getBankName());
        req.setOpenBankName("");

        req.setAccountName(bidCustomerDO.getBankUserName());
        req.setBankCardNum(bidCustomerDO.getBankCardNum());
        req.setBackPremium(acceptOrderInfoDO.getGuaranteeFee().doubleValue());
        req.setBackReasonDetail(backReasonDetail);


        Long centerId = acceptOrderInfoDO.getCenterId();
        Long orgId = acceptOrderInfoDO.getOrgId();


        String revokeNo = req.getPolicyNo();

        AcceptOrderInfoDO orderInfoDO = this.getByGuaranteeNo(centerId, orgId, revokeNo);
        if (orderInfoDO == null) {
            return FZBaseRespDTO.error("查无此投保申请记录");
        }
        RevokeFlagEnum flagEnum = RevokeFlagEnum.resolve(orderInfoDO.getRevokeFlag());
        if (flagEnum == RevokeFlagEnum.SUCCESS) {
            return FZBaseRespDTO.error("退保状态为[" + flagEnum + "]，不能再申请退保");
        }
        if (flagEnum == RevokeFlagEnum.PROCESSING) {
            return FZBaseRespDTO.error("退保审核中，请耐心等待审核结果");
        }
        if (flagEnum != RevokeFlagEnum.INIT && flagEnum != RevokeFlagEnum.FAILURE) {
            return FZBaseRespDTO.error("退保状态不是待退保状态，不能申请退保");
        }

        if (orderInfoDO.getStatus() == AcceptOrderStatus.FINISH.getStatus()) {
            return FZBaseRespDTO.error("保函已完成，不能退保申请");
        }
        if (orderInfoDO.getStatus() == AcceptOrderStatus.CANCEL.getStatus()) {
            return FZBaseRespDTO.error("保函已取消，不能退保申请");
        }
        if (orderInfoDO.getStatus() != AcceptOrderStatus.HAS_OUT_GUARANTEE.getStatus() && orderInfoDO.getStatus() != AcceptOrderStatus.REVOKE_FAIL.getStatus()) {
            return FZBaseRespDTO.error("已出函状态才能发起退保，未出函前可调用放弃投保申请");
        }


        AcceptOrderInfoDO updateOrderInfo = AcceptOrderInfoDO.builder()
                .id(orderInfoDO.getId())
                .revokeTime(new Date())
                .status(AcceptOrderStatus.REVOKE_SUCCESS.getStatus())
                .revokeFlag(RevokeFlagEnum.SUCCESS.getFlag())
                .remark(req.getBackReasonDetail()).build();

        ProjectInfoDO project = projectInfoService.selectById(orderInfoDO.getProjectId());

        RevokeOrderInfo revokeOrderInfo = RevokeOrderInfo.builder()
                .id(IdGenerate.getId())
                .centerId(centerId)
                .orgId(orgId)
                //通过保函编号关联受理订单号
                .revokeNo(revokeNo)
                .note(req.getBackReasonDetail())
                //备注字段存储 业务流水号
                .remark(req.getPolicyNo())
                .projectCode(project.getProjectCode()).projectName(orderInfoDO.getProjectName())
                .sectionCode(project.getSectionCode()).sectionName(orderInfoDO.getSectionName())
                .tenderer(project.getTenderer()).status(0)
                .bankName(req.getBankName())
                .accountName(req.getAccountName())
                .openBankName(req.getOpenBankName())
                .bankCardNum(req.getBankCardNum())
                .backPremium(req.getBackPremium() == null ? 0L : req.getBackPremium().longValue())
                .build();
        List<RevokeOrderAttachmentDO> attachmentDOS = null;
        if (req.getBackFileList() != null) {
            AtomicInteger index = new AtomicInteger(1);
            attachmentDOS = req.getBackFileList().stream().map(item -> {
                return RevokeOrderAttachmentDO.builder()
                        .revokeOrderId(revokeOrderInfo.getId())
                        .no(index.getAndIncrement())
                        .fileUrl(item.getBackFileUrl())
                        .fileName(item.getBackFileName())
                        .fileMd5(item.getBackFileMD5())
                        .build();
            }).collect(Collectors.toList());
        }

        revokeOrderInfoService.saveRevokeOrderInfo(revokeOrderInfo, attachmentDOS, updateOrderInfo);
        //退保审核通过设置发票冲红标识为待冲红
        invoiceInfoService.updateInvoiceReversal(acceptOrderInfoDO.getInvoiceId());

        JSONObject respInfoObject = FZApiCommonUtil.invalideGuarantee(acceptOrderInfoDO, backReasonDetail);
//        JSONObject respInfoObject = JSONObject.parseObject(respInfo);

        FZCompanyInfoDTO fzCompanyInfoDTO = null;
        if ("200".equals(respInfoObject.get("status").toString())) {
//            fzCompanyInfoDTO = JSONObject.parseObject(companyInfoObject.getString("data"), FZCompanyInfoDTO.class);

        } else {
            //{
            //  "status" : 1001,
            //  "msg" : "access_token非法或失效"
            //}

            log.error("获取[保函作废]失败，{}", respInfoObject.get("msg"));
            throw new RuntimeException(respInfoObject.get("msg").toString());
        }


        return FZBaseRespDTO.success("作废申请已受理");
    }

    /**
     * 理赔结果
     */
    @Transactional(rollbackFor = Exception.class)
    public FZBaseRespDTO claimSettlement(String acceptInfoId, String claimReason) {

        AcceptOrderInfoDO orderInfo = this.selectById(Long.parseLong(acceptInfoId));
        if (orderInfo == null) {
            return FZBaseRespDTO.error("查无此投保申请记录");
        }

//        GuaranteeDO guaranteeDO = guaranteeService.getGuaranteeByGuaranteeNo(orderInfo.getGuaranteeNo());
//        if (guaranteeDO == null) {
//            return HyMakeBaseRespDTO.error("查无此保函记录");
//        }

        if (orderInfo.getStatus() == AcceptOrderStatus.FINISH.getStatus()) {
            return FZBaseRespDTO.error("保函已完成，不能理赔申请");
        }
        if (orderInfo.getStatus() == AcceptOrderStatus.CANCEL.getStatus()) {
            return FZBaseRespDTO.error("保函已取消，不能理赔申请");
        }
        if (orderInfo.getStatus() != AcceptOrderStatus.HAS_OUT_GUARANTEE.getStatus()) {
            return FZBaseRespDTO.error("已出函状态才能发起理赔");
        }

        ClaimsStatus claimsStatus = ClaimsStatus.resolve(orderInfo.getClaimsStatus());
        if (claimsStatus == ClaimsStatus.SUCCESS) {
            return FZBaseRespDTO.error("理赔处理完成[" + claimsStatus + "]," + orderInfo.getClaimsRemark());
        }
        if (claimsStatus == ClaimsStatus.PROCESSING) {
            return FZBaseRespDTO.error("理赔处理中,不能重复发起理赔");
        }

        ProjectInfoDO projectInfoDO = projectInfoService.selectById(orderInfo.getProjectId());
        GuaranteeInstitutionDO institutionDO = institutionService.selectById(orderInfo.getInstitutionId());

        AcceptOrderInfoDO updateOrderInfo = AcceptOrderInfoDO.builder().id(orderInfo.getId())
                .claimsStatus(ClaimsStatus.SUCCESS.getStatus()).claimsRemark(claimReason).build();
        this.updateById(updateOrderInfo);

        RefundOrderInfoDO curDo = null;
        if (claimsStatus == ClaimsStatus.FAILURE) {
            curDo = refundOrderInfoService.getByGuaranteeNo(orderInfo.getGuaranteeNo());
            curDo.setRemark(claimReason);
            curDo.setApplyUserName(projectInfoDO.getTendererContact());
            curDo.setApplyUserPhone(projectInfoDO.getTendererContactTel());
            curDo.setStatus(RefundOrderStatus.REFUNDED.getStatus());

            refundOrderInfoService.updateById(curDo);
        } else {
            //配合后管进行 审核操作，审核操作中需要同步到 accepInfo中的理赔最终状态
            curDo = RefundOrderInfoDO.builder()
                    .id(IdGenerate.getId()).centerId(orderInfo.getCenterId())
                    .orgId(orderInfo.getOrgId()).guaranteeNo(orderInfo.getGuaranteeNo())
                    .centerOrderId(orderInfo.getCenterOrderId()).acceptOrderNo(orderInfo.getAcceptOrderNo())
                    .applyOrderNo(orderInfo.getApplyOrderNo())
                    .guaranteeType(orderInfo.getGuaranteeType()).guaranteeCategory(orderInfo.getGuaranteeCategory())
                    .guaranteeFee(orderInfo.getGuaranteeFee()).projectId(orderInfo.getProjectId()).projectName(projectInfoDO.getProjectName())
                    .sectionName(orderInfo.getSectionName())
                    .bidCustomerId(orderInfo.getBidCustomerId()).bidCustomerName(orderInfo.getBidCustomerName())
                    .bidIndate(orderInfo.getBidIndate())
                    .bidBond(projectInfoDO.getBidBond())
                    .institutionId(orderInfo.getInstitutionId())
                    .institutionName(institutionDO.getGuarantorName())
                    .attachmentId(orderInfo.getAttachmentId()).remark(claimReason)
                    .inviteCode(orderInfo.getInviteCode())
                    .applyUserName(projectInfoDO.getTendererContact()).applyUserPhone(projectInfoDO.getTendererContactTel())
                    .gmtCreate(Date.from(Instant.now())).gmtModified(Date.from(Instant.now())).userCreate("接口申请")
                    .status(RefundOrderStatus.REFUNDED.getStatus())
                    .build();
            refundOrderInfoService.insert(curDo);
        }


        JSONObject respInfoObject = FZApiCommonUtil.claimSettlement(curDo, projectInfoDO);
//        JSONObject companyInfoObject = JSONObject.parseObject(companyInfo);

        FZCompanyInfoDTO fzCompanyInfoDTO = null;
        if ("200".equals(respInfoObject.get("status").toString())) {
//            fzCompanyInfoDTO = JSONObject.parseObject(companyInfoObject.getString("data"), FZCompanyInfoDTO.class);
        } else {
            //{
            //  "status" : 1001,
            //  "msg" : "access_token非法或失效"
            //}

            log.error("获取[理赔结果通知]失败，{}", respInfoObject.get("msg"));
            throw new RuntimeException(respInfoObject.get("msg").toString());
        }


        return FZBaseRespDTO.success("理赔结果已通知");
    }

    /**
     * 申请订单修改接口，重新出函
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean updateGuarantee(AcceptOrderInfoDO orderInfo) {
        try {
            AcceptOrderStatusAuditVO auditVO = new AcceptOrderStatusAuditVO();
            auditVO.setId(orderInfo.getId());
            auditVO.setStatus(orderInfo.getStatus());
            auditVO.setAuditStatus(1);
            auditVO.setPayTime(orderInfo.getPayTime());
            auditVO.setTemplateId(orderInfo.getTemplateId());
            auditVO.setAuditRemark("申请订单修改接口，自动审核通过重新出函");
            //重新出函
            this.auditWaitPayConfirm(auditVO);
        } catch (Exception e) {
            log.error("重新出函失败：{}", e.getMessage(), e);
            throw new SystemRuntimeException(ErrorCode.ERROR, "申请订单修改接口，重新出函失败");
        }
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    public void saveInviteCode(Long acceptOrderId, String inviteCode) {
        AcceptOrderInfoDO updateAccept = AcceptOrderInfoDO.builder().id(acceptOrderId).inviteCode(inviteCode)
                .gmtModified(Date.from(Instant.now())).build();
        int num = this.updateById(updateAccept);
        if (num > 1) {
            log.error("更新业务编码失败；更新行数：{}", num);
            throw new SystemRuntimeException(ErrorCode.ERROR, "更新业务编码失败");
        }
    }

    public AcceptOrderInfoDO getAcceptOrderInfoByGuaranteeNo(@NotBlank(message = "保函编号不能为空") String cpolicyno) {
        return null;
    }

    public List<AcceptOrderInfoDO> findOrdersWithActiveVirtualCards() {
        AcceptOrderInfoDOCondition condition = AcceptOrderInfoDOCondition.builder()
                .andVirtualCardNoIsNotNull()
                .andCardStatusEq("ACTIVE");
        return this.selectList(condition.build());
    }
}
